#include "CCanvas.h"
#include "Base.h"
#include "Timer.h"
#include "Globals.h"
#include "Configuration.h"
#include <iostream>
#include <fstream>
#include "SoundEngine.h"
#include "Light.h"

 

static bool FULLSCREEN = false;
static int DISTANCE = 4;
static int SCREEN_WIDTH = 8;


void CCanvas::mousePressEvent (QMouseEvent *e)
{
	InputEngine * inputEngine = InputEngine::getInstance();
	inputEngine->mousePressed(e);
  QGLWidget::mousePressEvent(e);
} 

void CCanvas::keyPressEvent( QKeyEvent *e )
{
	InputEngine * inputEngine = InputEngine::getInstance();
	
	if (inputEngine->keyPressEvent(e)) {
		return;
	}
	
	switch (e->key()) {
		case  Qt::Key_F:
			if(!FULLSCREEN)
				window()->showFullScreen();
			else
				window()->showNormal();
			
			FULLSCREEN = !FULLSCREEN;
			break;
		case Qt::Key_P:
			_world.togglePause();
			std::cout<<"pause"<<std::endl;
			break;
		case Qt::Key_Q:
			Configuration::getInstance()->toggleDebugMode();
			break;
		case Qt::Key_E:
			SoundEngine::getInstance()->toggleSound();
			break;
		case Qt::Key_Y:
			Configuration::getInstance()->toggleCockpit();
			break;
    case Qt::Key_K:
      camera()->setPhysicalDistanceToScreen(++DISTANCE);
      break;
    case Qt::Key_L:
      camera()->setPhysicalScreenWidth(++SCREEN_WIDTH);
      break;
    case Qt::Key_M:
      camera()->setPhysicalDistanceToScreen(--DISTANCE);
      break;
    case Qt::Key_N:
      camera()->setPhysicalScreenWidth(--SCREEN_WIDTH);
      break;

	}
}

void CCanvas::keyReleaseEvent( QKeyEvent *e )
{
	InputEngine * inputEngine = InputEngine::getInstance();
	
	if (inputEngine->keyReleaseEvent(e)) {
		return;
	}
}

//-----------------------------------------------------------------------------

void CCanvas::init()
{

 

	Configuration::getInstance()->renderer = &_renderer;
	_world.setPlayer(&_player);
	InputEngine * inputEngine = InputEngine::getInstance();
	inputEngine->setWorld(&_world);
	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);			          // White Background
	glClearDepth(1.0f);									                // Depth Buffer Setup
	glEnable(GL_DEPTH_TEST);// Enables Depth Testing

	//glEnable(GL_CULL_FACE);
	//glDepthMask(GL_TRUE);
	glDepthFunc(GL_LEQUAL);								              // The Type Of Depth Testing To Do
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);	// Really Nice Perspective Calculations
	

	setFocusPolicy(Qt::StrongFocus);
	grabKeyboard();
	grabMouse();
	
	worldLight = Light::newLight(WMaterial(RGBd(0.6,0.6,0.6)), Point3d(5.0, 5.0, 5.0));
	_renderer.initialize();
	_world.onGameStarted();

  setStereoDisplay(true);
  // QDesktopWidget screen;
  //if (fabs((float)screen.width() / (float)screen.height()) > 2.0)
  // {
  camera()->setPhysicalDistanceToScreen(DISTANCE);
  camera()->setPhysicalScreenWidth(SCREEN_WIDTH);
  //}

};

//-----------------------------------------------------------------------------

void CCanvas::resizeGL(int width, int height)
{

  QGLViewer::resizeGL(width, height);
	// set up the window-to-viewport transformation
	glViewport( 0,0, width,height );
	
	// vertical camera opening angle
	double beta = 90.0;
	
	// aspect ratio
	double gamma;
	if (height > 0)
		gamma = width/(double)height;
	else
		gamma = width;
	
	// front and back clipping plane at
	double n = 1.0;
	double f = 760;
	
	// set projection matrix
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective( beta, gamma, n, f );
  camera()->setType(qglviewer::Camera::PERSPECTIVE);
  camera()->setSceneCenter(qglviewer::Vec(0,0,300));
  camera()->setZNearCoefficient(0.00005);
  camera()->setZClippingCoefficient(f+300);
  //showEntireScene();
  //printf("radius %g, distance to center %g", camera()->sceneRadius(), camera()->distanceToSceneCenter());

  //std::cout << std::endl;
  //std::cout<<camera()->zNear()<< " " << camera()->zFar()<<std::endl;


}
void CCanvas::drawSkyBox(){
	glDepthMask(false);
	
_renderer.renderSkyBox();
	
	glDepthMask(true);
}

//-----------------------------------------------------------------------------
void CCanvas::draw()
{

  glPushMatrix();
 
  // clear screen and depth buffer
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	
	// set model-view matrix
	glMatrixMode(GL_MODELVIEW);
	
	if(!_world.isPause()){
		_player.step(0.1);
	
		Point3d playerPosition=_player.position();
		Point3d direction = _player.velocity();
		direction.normalize();
		Point3d vp = playerPosition;
		Point3d q= vp+direction;
		Point3d upper = _player.upperNormal();
		
		glLoadIdentity();
		gluLookAt( 0, 0, 0, direction.x(),direction.y(),direction.z(), upper[0], upper[1], upper[2]);
		drawSkyBox();

		glLoadIdentity();
		gluLookAt( playerPosition.x(), playerPosition.y(), playerPosition.z(), q.x(), q.y(), q.z(), upper[0], upper[1], upper[2]);
	}
	else{
		glLoadIdentity();
		QFont myFont( "TypeWriter", 20, QFont::Bold);
		if(_player.hasWin()){
			this->renderText(0, 0, -1.5, QString("YOU WON!\r\n(Press P to proceed)"),myFont);
		}
		else if(!_player.alive()){
			this->renderText(0, 0, -1.5, QString("YOU ARE DEAD!!!\r\n(Press P to restart)"),myFont);
		}
		else{
			this->renderText(0.0, 0.0, -1.5, QString("PAUSE\r\n(Press P to continue)"),myFont);
		}
		
		return;
	}
	
	
	// turn on light
	glEnable( GL_NORMALIZE );
	
	worldLight->set();
	
	glShadeModel( GL_SMOOTH );
	
	//glMatrixMode(GL_MODELVIEW);
	_world.step(0.1);
	
	
	glMatrixMode(GL_MODELVIEW);
	
	
	_world.renderOn(&_renderer);
	
	tau += 1.0;
	
	InputEngine::getInstance()->processInputs();
	//swapBuffers();
  glPopMatrix();


}
